// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// Selectable.h : interface of the Selectable class
//

#pragma once

#include "Ref.h"

// ----------------------------------------------------------------------------
// Class "Selectable"
// ----------------------------------------------------------------------------
// Right now this is the root class of our hierarchy, meaning that most things
// in our scene are subclasses of it. We make it non-copyable, which means
// that most things in our scene can't be copied by the traditional means. This
// is very restrictive but we find that this way the semantics of client code
// are less confusing. Besides, the resulting code is more portable (where 
// by "portable" we mean that it can be adapted with little effort to other 
// languages like Java or C#) because we don't rely in copy ctors. or 
// assignment ops.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

class Selectable : public boost::enable_shared_from_this<Selectable>
{
public:

    // Returns a ref. counted pointer to a Selectable, conveniently cast
    // to the actual polymorphic type. For efficiency this cast uses
    // RTTI in debug builds, but reverts to an unsafe static cast in
    // release builds
    template<class T>
    ref<T> getRef();

    // --------------------------------------------------------------

    virtual ~Selectable() { }

    // --------------------------------------------------------------
    
    // Obtain or modify the name of this node
    // An node may have an empty name or two nodes in the
    // same tree may have the same name, but it's recommended
    // that each node is given a unique, meaningul name
    virtual std::wstring getName() const;
    virtual void setName(const std::wstring & name);

    // --------------------------------------------------------------
    // Serialization

    // TODO add Serializable interface
    virtual void read(std::wistream& is);
    virtual void write(std::wostream& os) const;

protected:

    // --------------------------------------------------------------
    // Only subclasses can be instantiated
    
    Selectable() { }

private:

    // --------------------------------------------------------------
    // See comment in members set/get_name
    
    std::wstring m_name;
};


// -------------------------------------------------------------------
// Implementation of inline members and templates


template<class T>
ref<T> Selectable::getRef() 
{
#ifdef _DEBUG
    return dyn_ptr_cast<T>(shared_from_this());
#else
    return static_ptr_cast<T>(shared_from_this());
#endif
 }